package com.yymx.toback.service.sms.impl;

import com.alibaba.fastjson.JSON;
import com.yymx.toback.common.base.BaseResult;
import com.yymx.toback.common.base.BaseServiceImpl;
import com.yymx.toback.common.constants.RedisConstants;
import com.yymx.toback.common.enums.ResultEnum;
import com.yymx.toback.common.enums.SmsStatusEnum;
import com.yymx.toback.common.enums.SmsTypeEnum;
import com.yymx.toback.common.enums.YunpianSmsTemplateEnum;
import com.yymx.toback.common.redis.RedisUtil;
import com.yymx.toback.common.sms.SmsFilterUtil;
import com.yymx.toback.common.sms.UserSmsStatics;
import com.yymx.toback.common.sms.YunPianSmsSdk;
import com.yymx.toback.common.util.DateUtils;
import com.yymx.toback.common.util.StringUtils;
import com.yymx.toback.dto.sms.entity.UserSms;
import com.yymx.toback.dto.sms.mapper.UserSmsMapper;
import com.yymx.toback.dto.sms.vo.UserSmsVo;
import com.yymx.toback.service.sms.IUserSmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * tb_user_sms(用户短信表) 服务实现类
 * </p>
 *
 * @author zcg
 * @since 2019-03-20
 */
@Service
public class UserSmsServiceImpl extends BaseServiceImpl<UserSmsMapper, UserSms> implements IUserSmsService {
    private Logger logger = LoggerFactory.getLogger(UserSmsServiceImpl.class);
    @Resource
    YunPianSmsSdk yunPianSmsSdk;
    @Resource
    private SmsFilterUtil smsFilterUtil;
    @Autowired
    private RedisUtil redisUtil;
    @Value("${sms.turnOn}")
    private String smsTurnOn;
    @Override
    public BaseResult send(UserSmsVo userSmsVo) {
        String uuid = UUID.randomUUID().toString();
        logger.info("UUID{},短信JSON:{}", uuid, JSON.toJSONString(userSmsVo));
        if (UserSmsStatics.TurnOn.ON.equals(smsTurnOn)) {
            logger.info("UUID{},发送短信开启", uuid);
        } else {
            logger.info("UUID{},发送短信关闭", uuid);
            return BaseResult.failMsg("发送短信关闭");
        }
        SmsTypeEnum smsTypeEnum = switchType("1");
        if(smsTypeEnum==null){
            return BaseResult.failMsg("短信发送类型错误");
        }
        try {
            smsFilterUtil.saveSmsLog(userSmsVo.getPhone(), userSmsVo.getRequestIp());
            BaseResult flag = yunPianSmsSdk.send(userSmsVo.getPhone(), userSmsVo.getContent(), userSmsVo.getIdentityCode(), smsTypeEnum);
            UserSms userSms = (UserSms)userSmsVo;
            userSms.setCreateTime(DateUtils.getSysDate());
            userSms.setUpdateTime(DateUtils.getSysDate());
            insert(userSms);
            if (BaseResult.success().getCode().equals(flag.getCode())) {
                userSms.setStatus(SmsStatusEnum.SEND_RECIVE.getStatus());
                updateById(userSms);
                return BaseResult.success();
            }
            return flag;
        } catch (Exception e) {
            return BaseResult.failMsg("短信服务处理异常"+e.getMessage());
        }
    }

    @Override
    public BaseResult send(YunpianSmsTemplateEnum smsTemplateEnum, String phone, String ip) {
        UserSms userSms = new UserSms();
        String indentifyCode = YunPianSmsSdk.createIndentifyCode(4);
        userSms.setContent(smsTemplateEnum.getDescription().replace("#code#",indentifyCode));
        String uuid = UUID.randomUUID().toString();
        userSms.setCreateTime(DateUtils.getSysDate());
        userSms.setUpdateTime(DateUtils.getSysDate());
        userSms.setPhone(phone);
        userSms.setType(SmsTypeEnum.NOMAL_MESSAGE.getTypeModel());
        logger.info("UUID{},短信JSON:{}", uuid, JSON.toJSONString(userSms));
        if (UserSmsStatics.TurnOn.ON.equals(smsTurnOn)) {
            logger.info("UUID{},发送短信开启", uuid);
        } else {
            logger.info("UUID{},发送短信关闭", uuid);
            return BaseResult.failMsg("发送短信关闭");
        }
        try {
            smsFilterUtil.saveSmsLog(phone, ip);
            BaseResult flag = yunPianSmsSdk.send(phone, userSms.getContent(), indentifyCode, SmsTypeEnum.NOMAL_MESSAGE);

            insert(userSms);
            if (BaseResult.success().getCode().equals(flag.getCode())) {
                userSms.setStatus(SmsStatusEnum.SEND_RECIVE.getStatus());
                updateById(userSms);
                return BaseResult.success();
            }
            return flag;
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResult.failMsg("短信服务处理异常"+e.getMessage());
        }
    }

    @Override
    public BaseResult sendByTime(UserSmsVo userSmsVo) {
        //定时发送
        Timer timer = new Timer();
        timer.schedule(new SmsTask(userSmsVo).setIp(userSmsVo.getRequestIp()), userSmsVo.getTime());
        return BaseResult.success();
    }

    class SmsTask extends TimerTask {
        private UserSmsVo smsVo;
        String ip;

        public SmsTask(UserSmsVo smsVo) {
            this.smsVo = smsVo;
        }

        public String getIp() {
            return ip;
        }

        public SmsTask setIp(String ip) {
            this.ip = ip;
            return this;
        }

        @Override
        public void run() {
            try {
                SmsTypeEnum smsTypeEnum = switchType(smsVo.getType());
                if(smsTypeEnum!=null){
                    smsFilterUtil.saveSmsLog(smsVo.getPhone(), smsVo.getRequestIp());
                    BaseResult flag = yunPianSmsSdk.send(smsVo.getPhone(), smsVo.getContent(), smsVo.getIdentityCode(),smsTypeEnum);
                    logger.info("定时短信发送" + DateUtils.getDateTime());
                    UserSms userSms = (UserSms)smsVo;
                    userSms.setCreateTime(DateUtils.getSysDate());
                    userSms.setUpdateTime(DateUtils.getSysDate());
                    insert(userSms);
                    if (BaseResult.success().getCode().equals(flag.getCode())) {
                        userSms.setStatus(SmsStatusEnum.SEND_RECIVE.getStatus());
                        updateById(userSms);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取当前的发送短信的类型
     *
     * @param type
     * @return
     */
    private SmsTypeEnum switchType(String type) {
        for (SmsTypeEnum smsTypeEnum : SmsTypeEnum.values()) {
            if (smsTypeEnum.getType() == Integer.valueOf(type)) {
                return smsTypeEnum;
            }
        }
        return null;
    }

    /**
     * 检测当前发送短信是否合法
     * @param userSmsVo
     * @return
     */
    private  boolean filterSms(UserSmsVo userSmsVo){

        if( smsFilterUtil.ipFilter(userSmsVo.getRequestIp()) && smsFilterUtil.canSendInMinutes(userSmsVo.getPhone()) && smsFilterUtil.mobileFilter(userSmsVo.getPhone())){
            return true;
        }
        return false;

    }

    @Override
    public BaseResult checkSms(UserSmsVo userSmsVo){
    	//短信验证返回200,前端根据 success 标签判断
		Map<String, Object> _map = new HashMap<>();
		_map.put("success", true);
        if(StringUtils.isBlank(userSmsVo.getPhone())){
    		_map.put("success", false);
            return BaseResult.successMsgAndData(ResultEnum.USER_PHONE_IS_NULL.getMsg(),_map);
        }
        //从redis中获取验证码
        String smsCode = smsCode(userSmsVo.getPhone());
        if(userSmsVo.getPhone().equals("15395713725") ){
            return BaseResult.fail();
        }
        if(StringUtils.isBlank(userSmsVo.getIdentityCode())){
    		_map.put("success", false);
            return BaseResult.successMsgAndData(ResultEnum.SMS_IDENTITYCODE_IS_NULL.getMsg(),_map);
        }
        if(StringUtils.isBlank(smsCode)){
    		_map.put("success", false);
            return BaseResult.successMsgAndData(ResultEnum.SMS_IDENTITYCODE_IS_INVALID.getMsg(),_map);

        }
        if(!StringUtils.equals(smsCode,userSmsVo.getIdentityCode())){
    		_map.put("success", false);
            return BaseResult.successMsgAndData(ResultEnum.SMS_IDENTITYCODE_IS_WRONG.getMsg(),_map);
        }
		return BaseResult.successData(_map);
    }

    private String smsCode(String phone){
        return (String)redisUtil.get(RedisConstants.REDIS_SMS_CODE+ phone);
    }

}
